{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2d124d22-de73-436b-86cd-9b162b469be8",
   "metadata": {
    "id": "2d124d22-de73-436b-86cd-9b162b469be8",
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "%pip install --upgrade pip\n",
    "\n",
    "# Uninstall conflicting packages\n",
    "%pip uninstall -y langchain-core langchain-openai langchain-experimental langchain-community langchain chromadb beautifulsoup4 python-dotenv PyPDF2 rank_bm25\n",
    "\n",
    "# Install compatible versions of langchain libraries\n",
    "%pip install langchain-core==0.3.6\n",
    "%pip install langchain-openai==0.2.1\n",
    "%pip install langchain-experimental==0.3.2\n",
    "%pip install langchain-community==0.3.1\n",
    "%pip install langchain==0.3.1\n",
    "\n",
    "# Install remaining packages\n",
    "%pip install chromadb==0.5.11\n",
    "%pip install beautifulsoup4==4.12.3\n",
    "%pip install python-dotenv==1.0.1\n",
    "%pip install PyPDF2==3.0.1 -q --user\n",
    "%pip install rank_bm25==0.2.2\n",
    "\n",
    "# new packages to download for this code lab!\n",
    "%pip install \"unstructured[pdf]\"\n",
    "%pip install pillow==10.4.0\n",
    "%pip install pydantic==2.9.2\n",
    "%pip install lxml==5.3.0\n",
    "%pip install matplotlib==3.9.2\n",
    "%pip install tiktoken==0.7.0\n",
    "!sudo apt-get -y install poppler-utils\n",
    "!sudo apt-get -y install tesseract-ocr\n",
    "\n",
    "# Restart the kernel after installation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f884314f-870c-4bfb-b6c1-a5b4801ec172",
   "metadata": {
    "executionInfo": {
     "elapsed": 10949,
     "status": "ok",
     "timestamp": 1718487838727,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "f884314f-870c-4bfb-b6c1-a5b4801ec172"
   },
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ['USER_AGENT'] = 'RAGUserAgent'\n",
    "import openai\n",
    "from langchain_openai import ChatOpenAI, OpenAIEmbeddings\n",
    "from langchain_core.output_parsers import StrOutputParser\n",
    "from langchain_core.runnables import RunnablePassthrough\n",
    "import chromadb\n",
    "from langchain_community.vectorstores import Chroma\n",
    "from dotenv import load_dotenv, find_dotenv\n",
    "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
    "from langchain_core.documents.base import Document\n",
    "\n",
    "# new\n",
    "from langchain.retrievers.multi_vector import MultiVectorRetriever\n",
    "from langchain_community.document_loaders import UnstructuredPDFLoader\n",
    "from langchain_core.runnables import RunnableLambda\n",
    "from langchain.storage import InMemoryStore\n",
    "from langchain_core.messages import HumanMessage\n",
    "import base64\n",
    "import uuid\n",
    "from IPython.display import HTML, display\n",
    "from PIL import Image\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a2a06702",
   "metadata": {
    "id": "a2a06702"
   },
   "outputs": [],
   "source": [
    "#### INDEXING ####"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b44fbbb5",
   "metadata": {
    "executionInfo": {
     "elapsed": 507,
     "status": "ok",
     "timestamp": 1718487906128,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "b44fbbb5"
   },
   "outputs": [],
   "source": [
    "# variables\n",
    "_ = load_dotenv(dotenv_path='env.txt')\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')\n",
    "openai.api_key = os.environ['OPENAI_API_KEY']\n",
    "llm = ChatOpenAI(model_name=\"gpt-4o-mini\", temperature=0)\n",
    "embedding_function = OpenAIEmbeddings()\n",
    "short_pdf_path = \"google-2023-environmental-report-short.pdf\"\n",
    "str_output_parser = StrOutputParser()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "06589e88",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 136,
     "referenced_widgets": [
      "59b608332cd74cb0b4cfeaef41698e01",
      "d40f81a1d39e40148a9fc98328b5f454",
      "75f6f7a4ef114186af44545e1ae2ebbf",
      "10cc265c297f4355a124fd4cdd5af7f4",
      "95da310d9dd14a85a43f170c433306d0",
      "a467a82ff9a7466d8ba5daaf0148559a",
      "5e7ef32b33964d1593f2f70719d03511",
      "0e137980c01347258d867313923988bf",
      "dedb51b7fee24a7b98a70528100d6ab1",
      "8d44e01b4d8c4fd78fa7902d9703e33c",
      "fc558588ceb9418cae6375d29b3d70c4"
     ]
    },
    "executionInfo": {
     "elapsed": 154689,
     "status": "ok",
     "timestamp": 1718488063754,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "06589e88",
    "outputId": "fb3ccbdf-ba70-4619-f78e-da5920312b24"
   },
   "outputs": [],
   "source": [
    "# Extract elements from PDF using LangChain and Unstructured - can take a little time to load!\n",
    "pdfloader = UnstructuredPDFLoader(\n",
    "    short_pdf_path,\n",
    "    mode=\"elements\",\n",
    "    strategy=\"hi_res\",\n",
    "    extract_image_block_types=[\"Image\",\"Table\"],\n",
    "    extract_image_block_to_payload=True, # converts images to base64 format\n",
    ")\n",
    "\n",
    "pdf_data = pdfloader.load()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "174b019c",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 302,
     "status": "ok",
     "timestamp": 1718488095158,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "174b019c",
    "outputId": "4a8e8fab-69da-494c-d332-54627f45d877"
   },
   "outputs": [],
   "source": [
    "texts = [doc for doc in pdf_data if doc.metadata[\"category\"] == \"NarrativeText\"]\n",
    "images = [doc for doc in pdf_data if doc.metadata[\"category\"] == \"Image\"]\n",
    "\n",
    "print(f\"TOTAL DOCS USED BEFORE REDUCTION: texts: {len(texts)} images: {len(images)}\")\n",
    "categories = set(doc.metadata[\"category\"] for doc in pdf_data)\n",
    "print(f\"CATEGORIES REPRESENTED: {categories}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "912b5fc9",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 211,
     "status": "ok",
     "timestamp": 1718488100539,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "912b5fc9",
    "outputId": "53579a2a-a349-471c-90c0-94e1678c3c93"
   },
   "outputs": [],
   "source": [
    "# cost savings: keep only the first 3 images to save compute costs for summarization\n",
    "if len(images) > 3:\n",
    "    images = images[:3]\n",
    "print(f\"total documents after reduction: texts: {len(texts)} images: {len(images)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "177f068d",
   "metadata": {
    "executionInfo": {
     "elapsed": 8121,
     "status": "ok",
     "timestamp": 1718488110430,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "177f068d"
   },
   "outputs": [],
   "source": [
    "def apply_prompt(img_base64):\n",
    "    # Prompt\n",
    "    prompt = \"\"\"You are an assistant tasked with summarizing images for retrieval. \\\n",
    "    These summaries will be embedded and used to retrieve the raw image. \\\n",
    "    Give a concise summary of the image that is well optimized for retrieval.\"\"\"\n",
    "\n",
    "    return [HumanMessage(content=[\n",
    "        {\"type\": \"text\", \"text\": prompt},\n",
    "        {\"type\": \"image_url\",\"image_url\": {\"url\": f\"data:image/jpeg;base64,{img_base64}\"},},\n",
    "    ])]\n",
    "\n",
    "# Just using the existing text as text summaries to save money, but you can add summaries here too in more robust applications\n",
    "text_summaries = [doc.page_content for doc in texts]\n",
    "\n",
    "# Store base64 encoded images, image summaries\n",
    "img_base64_list = []\n",
    "image_summaries = []\n",
    "\n",
    "# Apply to images\n",
    "for img_doc in images:\n",
    "    base64_image = img_doc.metadata[\"image_base64\"]\n",
    "    img_base64_list.append(base64_image)\n",
    "    message = llm.invoke(apply_prompt(base64_image))\n",
    "    image_summaries.append(message.content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "adf3a446",
   "metadata": {
    "executionInfo": {
     "elapsed": 1098,
     "status": "ok",
     "timestamp": 1718488123525,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "adf3a446"
   },
   "outputs": [],
   "source": [
    "vectorstore = Chroma(\n",
    "    collection_name=\"mm_rag_google_environmental\",\n",
    "    embedding_function=embedding_function\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0a55935a",
   "metadata": {
    "executionInfo": {
     "elapsed": 2553,
     "status": "ok",
     "timestamp": 1718488127918,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "0a55935a"
   },
   "outputs": [],
   "source": [
    "# mult-vector retriever - initialize the storage layer\n",
    "store = InMemoryStore()\n",
    "id_key = \"doc_id\"\n",
    "\n",
    "# Create the multi-vector retriever\n",
    "retriever_multi_vector = MultiVectorRetriever(\n",
    "    vectorstore=vectorstore,\n",
    "    docstore=store,\n",
    "    id_key=id_key,\n",
    ")\n",
    "\n",
    "# Helper function to add documents to the vectorstore and docstore\n",
    "def add_documents(retriever, doc_summaries, doc_contents):\n",
    "    doc_ids = [str(uuid.uuid4()) for _ in doc_contents]\n",
    "    summary_docs = [\n",
    "        Document(page_content=s, metadata={id_key: doc_ids[i]})\n",
    "        for i, s in enumerate(doc_summaries)\n",
    "    ]\n",
    "    content_docs = [\n",
    "        Document(page_content=doc.page_content, metadata={id_key: doc_ids[i]})\n",
    "        for i, doc in enumerate(doc_contents)\n",
    "    ]\n",
    "    retriever.vectorstore.add_documents(summary_docs)\n",
    "    retriever.docstore.mset(list(zip(doc_ids, content_docs)))\n",
    "\n",
    "# Add texts and images to vectorstore, vectorization is handled automatically\n",
    "if text_summaries:\n",
    "    add_documents(retriever_multi_vector, text_summaries, texts)\n",
    "if image_summaries:\n",
    "    add_documents(retriever_multi_vector, image_summaries, images)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f66095f8",
   "metadata": {
    "id": "f66095f8"
   },
   "outputs": [],
   "source": [
    "#### RETRIEVAL and GENERATION ####"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee91a987",
   "metadata": {
    "executionInfo": {
     "elapsed": 144,
     "status": "ok",
     "timestamp": 1718488162806,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "ee91a987"
   },
   "outputs": [],
   "source": [
    "# Split base64-encoded images and texts\n",
    "def split_image_text_types(docs):\n",
    "    b64_images = []\n",
    "    texts = []\n",
    "    for doc in docs:\n",
    "        # Check if the document is of type Document\n",
    "        if isinstance(doc, Document):\n",
    "            if doc.metadata.get(\"category\") == \"Image\":\n",
    "                base64_image = doc.metadata[\"image_base64\"]\n",
    "                b64_images.append(base64_image)\n",
    "            else:\n",
    "                texts.append(doc.page_content)\n",
    "        else:\n",
    "            # Handle the case when doc is a string\n",
    "            if isinstance(doc, str):\n",
    "                texts.append(doc)\n",
    "    return {\"images\": b64_images, \"texts\": texts}\n",
    "\n",
    "def img_prompt_func(data_dict):\n",
    "    formatted_texts = \"\\n\".join(data_dict[\"context\"][\"texts\"])\n",
    "    messages = []\n",
    "\n",
    "    # Adding image(s) to the messages if present\n",
    "    if data_dict[\"context\"][\"images\"]:\n",
    "        for image in data_dict[\"context\"][\"images\"]:\n",
    "            image_message = {\"type\": \"image_url\",\"image_url\": {\"url\": f\"data:image/jpeg;base64,{image}\"}}\n",
    "            messages.append(image_message)\n",
    "\n",
    "    # Adding the text for analysis\n",
    "    text_message = {\n",
    "        \"type\": \"text\",\n",
    "        \"text\": (\n",
    "            \"You are are a helpful assistant tasked with describing what is in an image.\\n\"\n",
    "            \"The user will ask for a picture of something.  Provide text that supports what was asked for.\\n\"\n",
    "            \"Use this information to provide an in-depth description of the aesthetics of the image. \\n\"\n",
    "            \"Be clear and concise and don't offer any additional commentary. \\n\"\n",
    "            f\"User-provided question: {data_dict['question']}\\n\\n\"\n",
    "            \"Text and / or images:\\n\"\n",
    "            f\"{formatted_texts}\"\n",
    "        ),\n",
    "    }\n",
    "    messages.append(text_message)\n",
    "    return [HumanMessage(content=messages)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bb1c4b48",
   "metadata": {
    "executionInfo": {
     "elapsed": 142,
     "status": "ok",
     "timestamp": 1718488164160,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "bb1c4b48"
   },
   "outputs": [],
   "source": [
    "# Create RAG chain\n",
    "chain_multimodal_rag = (\n",
    "        {\"context\": retriever_multi_vector | RunnableLambda(split_image_text_types), \"question\": RunnablePassthrough()}\n",
    "        | RunnableLambda(img_prompt_func)\n",
    "        | llm\n",
    "        | str_output_parser\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cfb8173c",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 174
    },
    "executionInfo": {
     "elapsed": 2677,
     "status": "ok",
     "timestamp": 1718488171300,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "cfb8173c",
    "outputId": "51721a79-10a3-4b38-97bc-0b27c16c15bf"
   },
   "outputs": [],
   "source": [
    "# Question - relevant question\n",
    "user_query = \"Picture of multiple wind turbines in the ocean.\"\n",
    "chain_multimodal_rag.invoke(user_query)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "42586d9e",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 694
    },
    "executionInfo": {
     "elapsed": 176,
     "status": "ok",
     "timestamp": 1718488180825,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "42586d9e",
    "outputId": "ea365f55-6f41-4c2a-c72a-c5e8933b2b14"
   },
   "outputs": [],
   "source": [
    "# Display a base64 image by rendering it with HTML\n",
    "def plt_img_base64(img_base64):\n",
    "    image_html = f'<img src=\"data:image/jpeg;base64,{img_base64}\" />'\n",
    "    display(HTML(image_html))\n",
    "\n",
    "plt_img_base64(img_base64_list[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5d55c72e",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 52
    },
    "executionInfo": {
     "elapsed": 221,
     "status": "ok",
     "timestamp": 1718488183761,
     "user": {
      "displayName": "",
      "userId": ""
     },
     "user_tz": 240
    },
    "id": "5d55c72e",
    "outputId": "83eb1e52-a2e2-4be1-aa54-ce1e7067a301"
   },
   "outputs": [],
   "source": [
    "image_summaries[1] # matches index of the image."
   ]
  }
 ],
 "metadata": {
  "colab": {
   "name": "CHAPTER14-3_MM_RAG.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  },
  "vscode": {
   "interpreter": {
    "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a"
   }
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "0e137980c01347258d867313923988bf": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "10cc265c297f4355a124fd4cdd5af7f4": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_8d44e01b4d8c4fd78fa7902d9703e33c",
      "placeholder": "​",
      "style": "IPY_MODEL_fc558588ceb9418cae6375d29b3d70c4",
      "value": " 217M/217M [00:01&lt;00:00, 155MB/s]"
     }
    },
    "59b608332cd74cb0b4cfeaef41698e01": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HBoxModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HBoxModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HBoxView",
      "box_style": "",
      "children": [
       "IPY_MODEL_d40f81a1d39e40148a9fc98328b5f454",
       "IPY_MODEL_75f6f7a4ef114186af44545e1ae2ebbf",
       "IPY_MODEL_10cc265c297f4355a124fd4cdd5af7f4"
      ],
      "layout": "IPY_MODEL_95da310d9dd14a85a43f170c433306d0"
     }
    },
    "5e7ef32b33964d1593f2f70719d03511": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "75f6f7a4ef114186af44545e1ae2ebbf": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "FloatProgressModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "FloatProgressModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "ProgressView",
      "bar_style": "success",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_0e137980c01347258d867313923988bf",
      "max": 216625723,
      "min": 0,
      "orientation": "horizontal",
      "style": "IPY_MODEL_dedb51b7fee24a7b98a70528100d6ab1",
      "value": 216625723
     }
    },
    "8d44e01b4d8c4fd78fa7902d9703e33c": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "95da310d9dd14a85a43f170c433306d0": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "a467a82ff9a7466d8ba5daaf0148559a": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "d40f81a1d39e40148a9fc98328b5f454": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_a467a82ff9a7466d8ba5daaf0148559a",
      "placeholder": "​",
      "style": "IPY_MODEL_5e7ef32b33964d1593f2f70719d03511",
      "value": "yolox_l0.05.onnx: 100%"
     }
    },
    "dedb51b7fee24a7b98a70528100d6ab1": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "ProgressStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "ProgressStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "bar_color": null,
      "description_width": ""
     }
    },
    "fc558588ceb9418cae6375d29b3d70c4": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
